package com.qf.commons.mysql.utils;

import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

/**
 * description: Mybatis插件工具方法
 * author: Ken
 * 公众号：Java架构栈
 */
public class MybatisUtils {

    /**
     * 直接获取到非代理的内置对象
     * @param target
     * @return
     */
    public static Object getNoProxyObject(Object target){
        MetaObject metaObject = SystemMetaObject.forObject(target);
        while (metaObject.hasGetter("h")) {
            //说明当前是一个代理对象
            //获取代理对象中持有的对象
            target = metaObject.getValue("h.target");
            metaObject = SystemMetaObject.forObject(target);
        }
        //直接返回非代理对象
        return target;
    }

    /**
     * select name,age,(select xxx from xxx) from student where id = (select xxx from xxx);
     * 返回一个SQL语句中 主表的 "from" 的index位置
     * @param beginIndex - 查找from的起始位置
     * @param sql
     * @return
     */
    public static Integer getMasterFormIndex(int beginIndex, String sql){
        if (sql == null) return -1;
        //从beginIndex处，往后查找，获取"from"关键字的下标
        int fromIndex = sql.indexOf(" from ", beginIndex);
        //如果fromIndex为-1，说明没有找到from关键字
        if (fromIndex == -1) return -1;

        //截取该位置前面的部分
        String sqlsub = sql.substring(0, fromIndex);

        //计数器
        int count = 0;

        //转换成char数组
        char[] chars = sqlsub.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];

            if (c == '(') count++;
            if (c == ')') count--;
        }

        //判断计数器
        if (count == 0) {
            //说明当前from关键字前面的正反括号刚好相同，说明这是主表的from关键字
            return fromIndex;
        } else {
            //说明当前并不是主表的from关键字，继续递归查找
            return getMasterFormIndex(fromIndex + 6, sql);
        }
    }

    public static void main(String[] args) {
        String sql = "select xxx,xxx,(select a,(select 1,2 from A),b from B) from Student where id = (select id from C)";
        String countSql = "select count(*) as count " + sql.substring(getMasterFormIndex(0, sql));
        System.out.println(countSql);
    }
}
